using ClearSpringNet.Stream.Cardinality;

namespace ClearSpringNet.Hash
{
    /// <summary>
    /// For more information, please refer to the following uri
    /// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param 
    /// </summary>
    public class FowlerNollVoHash : IHashProvider<string, uint>
    {
        /// <summary>
        /// 32 bit FNV-1a hashing. 
        /// Algorithm are as follows :- 
        /// 
        /// hash = offset_basis
        /// for each octet_of_data to be hashed
        ///     hash = hash xor octet_of_data
        ///     hash = hash * FNV_prime
        ///
        /// return hash
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public uint Hash(string text)
        {
            // var hash = 2166136261; // Some implementation uses this value 
            var hash = 16777619;  
            for (var i = 0; i < text.Length; ++i)
            {
                hash ^= text[i];
                hash += (hash << 1) + (hash << 4) + (hash << 7) +
                  (hash << 8) + (hash << 24);
            }
            return (uint) hash >> 0;
        }
    }
}